package threadutil

import (
	"fmt"
	"runtime"
)

var DefaultCallerSkip = 2 // 默认跳过两层调用

func GoSafe(fn func()) {
	go func() {
		defer func() {
			if err := recover(); err != nil {
				pc, file, line, ok := runtime.Caller(DefaultCallerSkip)
				if !ok {
					// 打印全部堆栈信息
					stackBuf := make([]byte, 1024)
					n := runtime.Stack(stackBuf, false)

					fmt.Printf("stack: %s\n", string(stackBuf[:n]))
					return
				}

				// 获取调用函数信息
				funcName := runtime.FuncForPC(pc).Name()
				fmt.Printf("Error occurred at %s:%d (%s)\n", file, line, funcName)
				return
			}
		}()

		fn()
	}()
}
